package com.hopedove.tempdemo.net

import com.google.gson.Gson
import com.google.gson.JsonElement
import com.google.gson.reflect.TypeToken
import com.hopedove.net.kotlin.CallResult
import com.hopedove.net.kotlin.ErrorResult
import com.hopedove.net.kotlin.SoapClient
import com.hopedove.net.kotlin.SuccessResult
import com.hopedove.tempdemo.net.data.*
import com.orhanobut.logger.Logger
import java.lang.reflect.Type

private const val TAG = "SoapApi"
private const val ERROR_UNKNOWN = "UnknownError"
private const val ERROR_DATA_EMPTY = "DataFieldEmptyError"
private const val ERROR_RESPONSE_NULL = "ResponseNullError"

class SoapApi(private val client: SoapClient = SoapClient()) {

    /**
     *  投产单接口
     */
    suspend fun getProductionNotice(request: GetProductionNoticeRequest): CallResult<GetProductionNoticeResponse> {
        val method = "tctzdToPrintList"
        val result = client.makeCall(method, Gson().toJson(request))
        return parse(result, object : TypeToken<GetProductionNoticeResponse>() {}.type)
    }


    /**
     *  根据车号查询接口
     */
    suspend fun queryNotice(no: String): CallResult<List<NoticeItem>> {
        val method = "tctzdListNoPaperQuery"
        val result = client.makeCall(method, no)
        return parse(result, object : TypeToken<List<NoticeItem>>() {}.type)
    }

    /**
     *  标签信息接口
     */
    suspend fun getNoticeBillInfo(no: String): CallResult<List<NoticeBill>> {
        val method = "tctzdLabelNoPapeQuery"
        val result = client.makeCall(method, no)
        return parse(result, object : TypeToken<List<NoticeBill>>() {}.type)
    }

    /**
     *  试样单接口
     */
    suspend fun getSampleNoticePrint(req: SampleNoticeRequest): CallResult<SampleNoticeResponse> {
        val method = "zzsydToPrintList"
        val result = client.makeCall(method, Gson().toJson(req))
        return parse(result, object : TypeToken<SampleNoticeResponse>() {}.type)
    }


    /**
     *  解析响应数据中的 data 字段
     */
    private fun <T> parse(rawResult: CallResult<String>, dataType: Type): CallResult<T> {
        return when (rawResult) {
            is SuccessResult -> {
                val result = parseCommonResponse(rawResult.value)
                Logger.json(rawResult.value)
                getData(result, dataType)
            }
            is ErrorResult -> {
                ErrorResult(rawResult.error)
            }
        }
    }

    /**
     *  解析服务端响应的通用格式
     */
    private fun parseCommonResponse(rawResponse: String): CallResult<JsonElement> {
        return try {
            val response = Gson().fromJson(rawResponse, CommonResponse::class.java)
            return if (response != null && response.status == "success") {
                if (!response.data.isJsonNull) {
                    SuccessResult(response.data)
                } else {
                    ErrorResult(ERROR_DATA_EMPTY)
                }
            } else {
                if (response == null) {
                    ErrorResult(ERROR_RESPONSE_NULL)
                } else {
                    ErrorResult(response.message ?: ERROR_UNKNOWN)
                }
            }
        } catch (e: Exception) {
            ErrorResult(e.toString())
        }
    }

    /**
     *  把通用格式中 data 解析为具体的对象
     */
    private fun <T> getData(data: CallResult<JsonElement>, type: Type): CallResult<T> {
        return try {
            when (data) {
                is SuccessResult -> SuccessResult(Gson().fromJson(data.value, type))
                is ErrorResult -> ErrorResult(data.error)
            }
        } catch (e: Exception) {
            ErrorResult(e.toString())
        }
    }

}